package com.yazi.mxz.behavior.quartz;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.hibernate.Paging;
import com.myframework.smhj.hibernate.Searching;
import com.myframework.smhj.hibernate.Page;
import com.myframework.smhj.hibernate.SearchingFactory;
import com.myframework.smhj.hibernate.Sort;
import com.yazi.mxz.behavior.common.ValueFactory;
import com.yazi.mxz.behavior.entity.beans.Region;
import com.yazi.mxz.behavior.entity.enums.DataSyncType;
import com.yazi.mxz.behavior.entity.enums.RegionField;
import com.yazi.mxz.behavior.entity.repository.DataSyncLog;
import com.yazi.mxz.behavior.repository.RegionRepository;
import com.yazi.mxz.behavior.service.RegionService;

/**
 * 地区数据同步(from oracle to mongodb)
 * @author mo_yq5
 * @date 2015-9-8
 */
public class RegionSyncQuartz extends SyncQuartzAbstract {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Resource
	RegionRepository regionRepository;
	
	@Resource
	RegionService regionService;
	
	public boolean work() {
		if (isWorking) {
			logger.info("地区 sync working");
			return false;
		}
		
		logger.info("地区 sync start：{}", regionRepository.count());
		
		isWorking = true;
		amount = 0;
		
		sycLog = dataSyncLogRepository.findOne(DataSyncType.REGION.ordinal());
		if (null == sycLog) {
			sycLog = new DataSyncLog();
			sycLog.setId(DataSyncType.REGION.ordinal());
			sycLog.setLastTime(-1L);
			dataSyncLogRepository.insert(sycLog);
		}
		
		// 最后更新的那条记录的时间作为下次同步的时间依据
		long latestTime = 0;
		
		Searching si = SearchingFactory.createSearching("updateTime", true, 1);
		
		Page<Region> page;
		try {
			
			page = regionService.listByGtUpdateTime(sycLog.getLastTime(), si);
			if (page.getPaging().getTotalResult() == 0) {
				latestTime = DateUtil.getTimeStamp();
				
			} else {
				
				latestTime = page.getList().get(0).getUpdateTime();
				
				// 从级别高的地区开始, 这样以便有可能由于父类覆盖子类从而减少操作
				Sort sort = new Sort("regionId");// pi.setOrderField("\"type\"");// 因type是oracle 关键字,不加引号则查询结果不正确,
				// 首次同步,则按级别低到高进行，勉强有些数据没有添加到库而没有被父类覆盖到，这样能保证先添加子类
				if (sycLog.getLastTime() == 0) {
					sort.setDesc(true);
				}
				List<Sort> sorts = new ArrayList<Sort>();
				sorts.add(sort);
				si.setSorts(sorts);
				si.setPageSize(Searching.MAX_PAGE_SIZE);
				checkRegion(si);
				
			}
			
			sycLog.setLastTime(latestTime);
			dataSyncLogRepository.save(sycLog);
			
			logger.info("地区 sync end: {}", amount);
			
		} catch (Exception e) {
			logger.error("地区同步异常：", e);
			return false;
		} finally {
			isWorking = false;			
		}
		
		return true;
	}
	
	private void checkRegion(Searching si) {
		
		Page<Region> page = regionService.listByGtUpdateTime(sycLog.getLastTime(), si);
		List<Region> list = page.getList();
    	for (Region region : list) {
    		
    		logger.info("地区 sync: {},{}", region.getRegionId(), region.getName());
    		
    		// region of mongodb
    		com.yazi.mxz.behavior.entity.repository.Region region0mg = new com.yazi.mxz.behavior.entity.repository.Region();
    		ValueFactory.combine(region, region0mg);
    		
    		if (null != region.getLnglat()) {
    			String[] lnglat = region.getLnglat().split(",");
    			region0mg.setLocation(new double[]{Double.parseDouble(lnglat[0]), Double.parseDouble(lnglat[1])});
    		}
    		
    		regionRepository.save(region0mg);
    		
    		if (region.getCoverType() != 0) {
    			coverSubRegion(region.getCoverType(), region0mg);

        		region.setCoverType(0);
        		regionService.modify(region);
    		}
    		
		}

    	amount += list.size();
    	Paging pi = page.getPaging();
    	if (pi.getNowPage() < pi.getTotalPage()) {
    		si.setNowPage(pi.getNowPage() + 1);
    		checkRegion(si);
    	}
    	
	}
	
	/**
	 * 覆盖子级
	 * @param parent
	 */
	private void coverSubRegion(int coverType, com.yazi.mxz.behavior.entity.repository.Region parent) {
		if (coverType == 0) {
			return;
		}
		boolean coverAds = (coverType & (1 << RegionField.ADS.ordinal())) > 0;
		boolean coverWords = (coverType & (1 << RegionField.WORDS.ordinal())) > 0;
		// region of mongodb
		List<com.yazi.mxz.behavior.entity.repository.Region> list0mg = regionRepository.findByParentId(parent.getRegionId());
		for (com.yazi.mxz.behavior.entity.repository.Region region0mg : list0mg) {
			
			if (coverAds) {
				region0mg.setAds(parent.getAds());
			}
			if (coverWords) {
				region0mg.setWords(parent.getWords());
			}
			logger.info("覆盖：{},{},{}", 
					new Object[]{coverType, region0mg.getRegionId(), region0mg.getName()});
			region0mg = regionRepository.save(region0mg);
			
			coverSubRegion(coverType, region0mg);
		}
		
	}

}
